package web.controller;

import com.alibaba.excel.EasyExcel;
import config.SpringContextUtil;
import entity.Course;
import entity.Leave;
import entity.LeaveData;
import entity.Student;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import service.CourseService;
import service.LeaveService;
import serviceImpl.CourseServiceImpl;
import serviceImpl.LeaveServiceImpl;

import java.io.*;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@WebServlet(name = "leave", urlPatterns = "/leave")
public class LeaveServlet extends HttpServlet {
    private String leave_list_page = "/WEB-INF/views/student/student_leave_list.jsp";
    private String leave_viewAdd_page = "/WEB-INF/views/student/student_leave_add.jsp";
    private String instructor_leave_list_page = "/WEB-INF/views/instructor/instructor_leave_list.jsp";
    private String instructor_leave_viewExamine_page = "/WEB-INF/views/instructor/instructor_leave_examine.jsp";
    private String instructor_leave_viewExport_page = "/WEB-INF/views/instructor/instructor_export_leave_list.jsp";
    @Autowired
    private LeaveService leaveService;
    @Autowired
    private CourseService courseService;

    @Override
    public void init() throws ServletException {
        this.leaveService = (LeaveServiceImpl) SpringContextUtil.getBean("leaveServiceImpl", LeaveServiceImpl.class);
        this.courseService = (CourseServiceImpl) SpringContextUtil.getBean("courseServiceImpl", CourseServiceImpl.class);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String action = req.getParameter("action");
        if (action == null) {
            List<Leave> leaves = leaveService.getAllLeave();
            req.setAttribute("leaves", leaves);
            RequestDispatcher dispatcher = req.getRequestDispatcher(leave_list_page);
            dispatcher.forward(req, resp);
        } else if (action.equals("delete")) {
            String leaveID = req.getParameter("leaveID");
            boolean flag = leaveService.deleteLeave(leaveID);
            if (flag) {
                String message = "删除成功!";
                resp.setContentType("text/html;charset=UTF-8");
                String jsCode = "<script>alert('" + message + "');window.location.href='" + req.getContextPath() + "/leave';</script>";
                resp.getWriter().write(jsCode);
            }
        } else if (action.equals("viewAdd")) {
            /*
             * 给请假申请表单生成leaveID
             * */
            LocalDateTime now = LocalDateTime.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
            String text = now.format(formatter);
            SecureRandom random = new SecureRandom();
            int randomNum = 100 + random.nextInt(900);
            String randomNumberString = String.valueOf(randomNum);
            String leaveID = (text + randomNumberString);
            req.setAttribute("leaveID", leaveID);
            /*
             * 将课程列表传入
             * */
            List<Course> courses = courseService.getAllCourses();
            req.setAttribute("courses", courses);
            RequestDispatcher dispatcher = req.getRequestDispatcher(leave_viewAdd_page);
            dispatcher.forward(req, resp);

        } else if (action.equals("add")) {
            String leaveID = req.getParameter("leaveID");
            String courseID = req.getParameter("courseID");
            String reason = req.getParameter("reason");
            int daynum = Integer.parseInt(req.getParameter("daynum"));
            /*
             * 生成当下时间用作请假申请时间(applytime)
             * */
            LocalDateTime now = LocalDateTime.now();
            Date applytime = Date.from(now.atZone(ZoneId.systemDefault()).toInstant());
            /*
             * 获取存在会话里的学号
             * */
            Student student = (Student) req.getSession().getAttribute("student");
            String stuNo = student.getStuID();
            String status = "0";
            Leave leave = new Leave(leaveID, courseID, reason, daynum, stuNo, applytime, status);
            boolean flag = leaveService.addLeave(leave);
            if (flag) {
                String message = "添加成功!";
                resp.setContentType("text/html;charset=UTF-8");
                String jsCode = "<script>alert('" + message + "');window.location.href='" + req.getContextPath() + "/leave';</script>";
                resp.getWriter().write(jsCode);
            }
        } else if (action.equals("viewLeavelist")) {
            List<Leave> leaves = leaveService.getAllLeave();
            req.setAttribute("leaves", leaves);
            RequestDispatcher dispatcher = req.getRequestDispatcher(instructor_leave_list_page);
            dispatcher.forward(req, resp);
        } else if (action.equals(("viewExamine"))) {
            String leaveID = req.getParameter("leaveID");
            Leave leave = leaveService.getLeaveByLeaveID(leaveID);
            req.setAttribute("leave", leave);
            RequestDispatcher dispatcher = req.getRequestDispatcher(instructor_leave_viewExamine_page);
            dispatcher.forward(req, resp);
        } else if (action.equals("examine")) {
            String leaveID = req.getParameter("leaveID");
            String opinion = req.getParameter("opinion");
            String status = req.getParameter("status");
            /*
             * 生成当下时间用作请假审核时间(audittime)
             * */
            LocalDateTime now = LocalDateTime.now();
            Date audittime = Date.from(now.atZone(ZoneId.systemDefault()).toInstant());
            Leave leave = new Leave(leaveID, opinion, status, audittime);
            boolean flag = leaveService.examineLeave(leave);
            if (flag) {
                String message = "审核成功!";
                resp.setContentType("text/html;charset=UTF-8");
                String jsCode = "<script>alert('" + message + "');window.location.href='" + req.getContextPath() + "/leave?action=viewLeavelist';</script>";
                resp.getWriter().write(jsCode);
            }
        } else if (action.equals("search")) {
            String leaveID = req.getParameter("leaveID");
            String courseID = req.getParameter("courseID");
            String stuNo = req.getParameter("stuNo");
            List<Leave> leaves = leaveService.searchLeave(leaveID, courseID, stuNo);
            req.getSession().setAttribute("leaves", leaves);
            req.setAttribute("leaves", leaves);
            /*
             * 处理时间数据上的格式
             * */
            /*SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            List<String> applytimes = new ArrayList<>();
            List<String> audittimes = new ArrayList<>();
            for (Leave leave : leaves){
                applytimes.add(sdf.format(leave.getApplytime()));
                audittimes.add(sdf.format(leave.getAudittime()));
            }
            req.setAttribute("applytimes", applytimes);
            req.setAttribute("audittimes", audittimes);*/
            RequestDispatcher dispatcher = req.getRequestDispatcher(instructor_leave_viewExport_page);
            dispatcher.forward(req, resp);

        } else if (action.equals("viewExport")) {
            RequestDispatcher dispatcher = req.getRequestDispatcher(instructor_leave_viewExport_page);
            dispatcher.forward(req, resp);
        } else if (action.equals("export")) {
            List<Leave> leaves = (List<Leave>) req.getSession().getAttribute("leaves");
            /*
             * 将会话中数据转成LeaveData类的数组中
             * */
            List<LeaveData> leaveData = new ArrayList<>();
            for (Leave leave : leaves) {
                LeaveData leaveData1 = new LeaveData(leave.getLeaveID(), leave.getCourseID(), leave.getReason(), leave.getDaynum(), leave.getStuNo(), leave.getApplytime(), leave.getStatus(), leave.getAudittime(), leave.getOpinion());
                leaveData.add(leaveData1);
            }
            try {
                // 生成Excel文件
                String realPath = req.getServletContext().getRealPath("/static/");
                File directory = new File(realPath);
                if (!directory.exists()) {
                    directory.mkdirs(); // 创建目录
                }
                String fileName = "请假单数据" + ".xlsx";
                File tempFile = File.createTempFile(fileName, ".xlsx", new File(realPath));
                String sheetName = "Sheet1";

                // 写入数据
                EasyExcel.write(tempFile.getAbsolutePath(), LeaveData.class)
                        .sheet(sheetName)
                        .doWrite(leaveData);

                // 设置响应头，让用户可以下载文件
                resp.setContentType("application/vnd.ms-excel");
                resp.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(tempFile.getName(), "UTF-8"));

                // 输出文件到响应流
                try (InputStream in = new FileInputStream(tempFile);
                     OutputStream out = resp.getOutputStream()) {
                    byte[] buffer = new byte[1024];
                    int length;
                    while ((length = in.read(buffer)) != -1) {
                        out.write(buffer, 0, length);
                    }
                }

                // 删除临时文件
                boolean delete = tempFile.delete();
                if (!delete) {
                    // 日志记录或处理文件删除失败的情况
                }
            } catch (Exception e) {
                // 记录异常信息到日志文件
                // 给用户一个友好的错误消息
                resp.getWriter().write("An error occurred while generating the Excel file.");
                e.printStackTrace();
            }

        }
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }
}
